<?php
/**
 * Created by PhpStorm.
 * User: yf
 * Date: 2018/10/26
 * Time: 5:39 PM
 */

namespace App\HttpController\Api\VersionOne;


use App\Model\CouponsGroupLogModel;
use App\Model\UserMoneyModel;
use App\Model\UserOpenModel;
use App\Model\UserModel;
use App\Model\UserWechatOpenModel;
use App\Utility\CommonTool;
use EasySwoole\Http\Message\Status;
use EasySwoole\HttpAnnotation\AnnotationTag\Param;
use EasySwoole\HttpAnnotation\AnnotationTag\Method;
use EasySwoole\ORM\Db\ClientInterface;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Exception\Exception;
use Throwable;

class Auth extends VersionBase
{
    protected $whiteList = ['weChatLogin'];

    /**
     * WeChatLogin
     * 微信登陆,参数验证注解写法
     * @Method(allow={POST})
     * @Param(name="nick_name", alias="昵称", required="", notEmpty="不能为空")
     * @Param(name="sex", alias="性别", required="", integer="", min="0", lengthMax="1", notEmpty="不能为空")
     * @Param(name="head_portrait", alias="头像", required="", notEmpty="不能为空"))
     * @Param(name="openid", alias="微信OPENID", required="", notEmpty="不能为空"))
     * @Param(name="unionid", alias="微信UNIONID", required="", notEmpty="不能为空"))
     * @Param(name="channel", alias="渠道", required="", integer="", min="1", lengthMax="3", notEmpty="不能为空")
     * @throws Exception
     * @throws Throwable
     */
    function weChatLogin()
    {
        $param = $this->request()->getRequestParam();

        /* 加锁,防止用户多次提交 */
        $lockRes = CommonTool::redisLock('login_' . $param['openid']);
        if (!$lockRes) {
            return $this->writeJson(Status::CODE_BAD_REQUEST, [], '请勿重复请求~');
        }

        // 查询第三方登录信息
        $otherLogin = DbManager::getInstance()->invoke(function ($client) use ($param) {
            return UserOpenModel::invoke($client)->where('user_type', 1)->where('certificate', $param['openid'])->get();
        });

        if ($otherLogin) {
            // 更新操作
            $user = DbManager::getInstance()->invoke(function (ClientInterface $client) use ($otherLogin) {
                try {
                    // 开启事务
                    DbManager::getInstance()->startTransaction($client);
                    $user = UserModel::invoke($client)->get($otherLogin->user_id);
                    $user->nick_name = $param['nick_name'] ?? '';
                    $user->sex = $param['sex'] ?? 0;
                    $user->headimg_url = $param['head_portrait'] ?? $user->headimg_url;
                    $user->update_time = time();
                    $user->update();
                    return $user;
                } catch (Throwable  $e) {
                    // 回滚事务
                    DbManager::getInstance()->rollback($client);
                    return false;
                } finally {
                    // 提交事务
                    DbManager::getInstance()->commit($client);
                }
            });
        } else {
            // 增加操作
            $user = DbManager::getInstance()->invoke(function (ClientInterface $client) use ($param) {
                try {
                    // 开启事务
                    $userInsertId = UserModel::invoke($client)->data([
                        'nick_name' => ($param['nick_name'] ?? ''),
                        'sex' => ($param['sex'] ?? 0),
                        'headimg_url' => ($param['head_portrait'] ?? 'http://thirdwx.qlogo.cn/mmopen/RFjSTRFhODWcXL8AyLyLNUyWuhme04f8yeflic0TuwMrNdfjVfrZ2jTaBQlrGXv7oKsA7rz2o4ibFdPljjIkXtHOJ1vyARrAoo/132'),
                        'phone' => '',
                        'real_name' => '',
                        'withdrawal_account' => '',
                        'create_time' => time(),
                        'update_time' => time(),
                        'frid' => ($param['channel'] ?? 1),
                        'unique_id' => '',
                        'is_real' => 1,
                    ], false)->save();

                    // 更新唯一ID,作用:自家统计留存率
                    $user = UserModel::invoke($client)->get($userInsertId);
                    $user->unique_id = strval(strtolower(md5($userInsertId . time() . $user->frid)) . '_' . date('Ymd'));
                    $user->update();

                    // 添加用户余额
                    UserMoneyModel::invoke($client)->addUserMoney($user->id);

                    // 添加到微信体系
                    UserWechatOpenModel::invoke($client)->addUserWechatOpen($param['openid'], $param['unionid'], 1);

                    // 添加用户第三方密钥
                    UserOpenModel::invoke($client)->addUserOpen($user->id, $param['openid'], 1);

                    return $user;
                } catch (Throwable  $e) {
                    // 回滚事务
                    DbManager::getInstance()->rollback($client);
                    return false;
                } finally {
                    // 提交事务
                    DbManager::getInstance()->commit($client);
                }
            });
        }

        CommonTool::redisUnlock('login_' . $param['openid']);

        if (!$user) {
            return $this->writeJson(Status::CODE_BAD_REQUEST, [], "登录失败");
        } else {
            $newcomer = DbManager::getInstance()->invoke(function ($client) use ($user) {
                return CouponsGroupLogModel::invoke($client)->where('user_id', $user->id)->where('group_id', 1)->get();
            });

            if (!$newcomer) {
                $newcomerBoolean = 1;
            } else {
                $newcomerBoolean = 0;
            }

            return $this->writeJson(Status::CODE_OK, [
                'id' => intval($user->id),
                'unique_id' => strval($user->unique_id),
                'access_token' => $user->makeToken(),
                'expire_in' => intval($user->getTokenExp()),
                'access_type' => 'Bearer',
                'login_time' => time(),
                'newcomer' => intval($newcomerBoolean),
            ], "success");
        }
    }
}
